package initialize

import (
	"fmt"
	"log"  // 导入log包
	"sync" // 导入sync包
	"time"

	mqtt "github.com/eclipse/paho.mqtt.golang"
)

var (
	mqttClient        mqtt.Client
	mqttOnce          sync.Once           // 用于确保初始化函数只执行一次
	messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
		fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
	}

	connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
		fmt.Println("Connected to MQTT Broker")
	}

	connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
		fmt.Printf("MQTT Connection lost: %v\n", err)
		// 自动重连
		for {
			fmt.Println("Attempting to reconnect to MQTT broker...")
			if token := client.Connect(); token.Wait() && token.Error() != nil {
				fmt.Printf("Failed to reconnect: %v\n", token.Error())
				time.Sleep(5 * time.Second)
				continue
			}
			fmt.Println("Successfully reconnected to MQTT broker")
			break
		}
	}
)

// InitMQTT 初始化 MQTT 客户端，并确保只初始化一次
func InitMQTT() mqtt.Client {
	mqttOnce.Do(func() {
		mqttConfig := Config.Mqtt
		broker := mqttConfig.Broker
		opts := mqtt.NewClientOptions()
		opts.AddBroker(broker)
		opts.SetClientID(mqttConfig.ClientID)
		opts.SetUsername(mqttConfig.Username)
		opts.SetPassword(mqttConfig.Password)
		opts.SetDefaultPublishHandler(messagePubHandler)
		opts.OnConnect = connectHandler
		opts.OnConnectionLost = connectLostHandler
		opts.SetCleanSession(true)

		// 设置重连相关参数
		opts.SetKeepAlive(60 * time.Second)
		opts.SetPingTimeout(10 * time.Second)
		opts.SetMaxReconnectInterval(5 * time.Second)
		opts.SetConnectRetryInterval(1 * time.Second)
		opts.SetConnectTimeout(5 * time.Second)
		opts.SetAutoReconnect(true)                   // 启用自动重连
		opts.SetMaxReconnectInterval(1 * time.Minute) // 设置最大重连间隔
		opts.SetResumeSubs(true)                      // 重连后自动恢复订阅

		// 创建并连接客户端
		client := mqtt.NewClient(opts)
		if token := client.Connect(); token.Wait() && token.Error() != nil {
			log.Fatalf("Failed to connect to MQTT broker: %v", token.Error())
		}
		mqttClient = client
		log.Println("MQTT client initialized and connected successfully.")
	})

	return mqttClient
}
